Skip to main content

🐍 Ngày 44 Python 365 ngày | Phân tích giá BTCUSDT với Plotly

Phân tích giá BTCUSDT

Hôm nay, chúng ta sẽ thu thập dữ liệu từ cặp tiền mã hóa BTCUSDT trên sàn Binance và hiển thị biểu đồ tương tác bằng thư viện Plotly.

🎯 Mục tiêu

  • Kết nối API Binance để lấy dữ liệu.
  • Phân tích và hiển thị giá BTC theo thời gian.
  • Tạo biểu đồ tương tác với Plotly.

🧰 Cài đặt thư viện

Trước khi bắt đầu, chúng ta cần cài đặt các thư viện cần thiết:

pip install python-binance pandas plotly

🔌 Lấy dữ liệu từ Binance

Chúng ta sẽ sử dụng thư viện python-binance để kết nối với API của Binance và lấy dữ liệu lịch sử giá của BTCUSDT.

from binance.client import Client
import pandas as pd
from datetime import datetime
import plotly.graph_objects as go

# Thay thế bằng API key và secret của bạn
api_key = 'your_api_key'
api_secret = 'your_api_secret'

client = Client(api_key, api_secret)

# Lấy dữ liệu nến (candlestick)
klines = client.get_klines(symbol='BTCUSDT', interval=Client.KLINE_INTERVAL_1HOUR, limit=100)

# Chuyển đổi dữ liệu thành DataFrame
df = pd.DataFrame(klines, columns=[
'open_time', 'open', 'high', 'low', 'close', 'volume',
'close_time', 'quote_asset_volume', 'number_of_trades',
'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'
])

# Chuyển đổi kiểu dữ liệu
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
df['close_time'] = pd.to_datetime(df['close_time'], unit='ms')
df[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']].astype(float)

print(df[['open_time', 'open', 'high', 'low', 'close']].head())

Đoạn mã này sẽ:

  1. Kết nối tới API Binance sử dụng API key và secret
  2. Lấy 100 nến 1 giờ gần nhất cho cặp BTCUSDT
  3. Chuyển đổi dữ liệu thành DataFrame pandas
  4. Chuyển đổi các cột thời gian thành định dạng datetime và các cột giá trị thành số thực
  5. Hiển thị 5 dòng đầu tiên của dữ liệu

📊 Vẽ biểu đồ giá với Plotly

Sau khi đã có dữ liệu, chúng ta sẽ sử dụng Plotly để vẽ biểu đồ nến tương tác:

fig = go.Figure(data=[go.Candlestick(
x=df['open_time'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
name="BTCUSDT"
)])

fig.update_layout(
title='Biểu đồ giá BTCUSDT (1 giờ gần nhất)',
xaxis_title='Thời gian',
yaxis_title='Giá (USDT)',
xaxis_rangeslider_visible=False,
template='plotly_dark'
)

fig.show()

Đoạn mã này tạo một biểu đồ nến tương tác với:

  • Trục x là thời gian
  • Trục y là giá của BTC (tính bằng USDT)
  • Giao diện tối (plotly_dark)
  • Bỏ thanh trượt phạm vi trên trục x

📈 Phân tích dữ liệu nâng cao

Thêm đường trung bình động (Moving Average)

Chúng ta có thể thêm các chỉ báo kỹ thuật như đường trung bình động để hỗ trợ phân tích:

# Tính MA20 và MA50
df['MA20'] = df['close'].rolling(window=20).mean()
df['MA50'] = df['close'].rolling(window=50).mean()

# Tạo biểu đồ với MA
fig = go.Figure()

# Thêm biểu đồ nến
fig.add_trace(go.Candlestick(
x=df['open_time'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
name="BTCUSDT"
))

# Thêm đường MA20
fig.add_trace(go.Scatter(
x=df['open_time'],
y=df['MA20'],
line=dict(color='orange', width=2),
name="MA20"
))

# Thêm đường MA50
fig.add_trace(go.Scatter(
x=df['open_time'],
y=df['MA50'],
line=dict(color='blue', width=2),
name="MA50"
))

fig.update_layout(
title='Biểu đồ giá BTCUSDT với đường trung bình động',
xaxis_title='Thời gian',
yaxis_title='Giá (USDT)',
xaxis_rangeslider_visible=False,
template='plotly_dark'
)

fig.show()

Biểu đồ khối lượng giao dịch (Volume)

Để phân tích khối lượng giao dịch cùng với giá:

# Tạo biểu đồ với khối lượng
fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
vertical_spacing=0.03, row_heights=[0.7, 0.3])

# Thêm biểu đồ nến vào hàng 1
fig.add_trace(go.Candlestick(
x=df['open_time'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
name="BTCUSDT"
), row=1, col=1)

# Thêm biểu đồ khối lượng vào hàng 2
colors = ['green' if row['close'] >= row['open'] else 'red' for _, row in df.iterrows()]
fig.add_trace(go.Bar(
x=df['open_time'],
y=df['volume'],
marker_color=colors,
name="Volume"
), row=2, col=1)

fig.update_layout(
title='Biểu đồ giá và khối lượng giao dịch BTCUSDT',
xaxis_title='Thời gian',
yaxis_title='Giá (USDT)',
xaxis2_title='Thời gian',
yaxis2_title='Khối lượng',
xaxis_rangeslider_visible=False,
template='plotly_dark'
)

fig.show()

📋 Lưu và tải dữ liệu

Để lưu dữ liệu đã thu thập để sử dụng sau này:

# Lưu dữ liệu vào file CSV
df.to_csv('btcusdt_historical_data.csv', index=False)

# Để tải lại dữ liệu
# df = pd.read_csv('btcusdt_historical_data.csv')
# df['open_time'] = pd.to_datetime(df['open_time'])
# df['close_time'] = pd.to_datetime(df['close_time'])

🔄 So sánh BTCUSDT và ETHUSDT

Chúng ta có thể so sánh biến động giá của Bitcoin và Ethereum:

# Lấy dữ liệu ETHUSDT
eth_klines = client.get_klines(symbol='ETHUSDT', interval=Client.KLINE_INTERVAL_1HOUR, limit=100)

# Chuyển đổi dữ liệu thành DataFrame
eth_df = pd.DataFrame(eth_klines, columns=[
'open_time', 'open', 'high', 'low', 'close', 'volume',
'close_time', 'quote_asset_volume', 'number_of_trades',
'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'
])

# Chuyển đổi kiểu dữ liệu
eth_df['open_time'] = pd.to_datetime(eth_df['open_time'], unit='ms')
eth_df['close'] = eth_df['close'].astype(float)

# Chuẩn hóa giá để so sánh
btc_normalized = df['close'] / df['close'].iloc[0]
eth_normalized = eth_df['close'] / eth_df['close'].iloc[0]

# Tạo biểu đồ so sánh
fig = go.Figure()

fig.add_trace(go.Scatter(
x=df['open_time'],
y=btc_normalized,
mode='lines',
name='BTCUSDT'
))

fig.add_trace(go.Scatter(
x=eth_df['open_time'],
y=eth_normalized,
mode='lines',
name='ETHUSDT'
))

fig.update_layout(
title='So sánh biến động giá BTCUSDT và ETHUSDT (chuẩn hóa)',
xaxis_title='Thời gian',
yaxis_title='Giá tương đối (so với giá ban đầu)',
template='plotly_dark'
)

fig.show()

📌 Bài tập gợi ý

  1. Tạo biểu đồ volume giao dịch theo thời gian:

    • Sử dụng biểu đồ cột để hiển thị khối lượng giao dịch
    • Phân biệt khối lượng trong các phiên tăng/giảm bằng màu sắc khác nhau
  2. So sánh giá BTCUSDT với ETHUSDT:

    • Xem xét tương quan giữa hai cặp tiền
    • Vẽ biểu đồ tỷ lệ giá BTC/ETH theo thời gian
  3. Lưu dữ liệu nến về file .csv:

    • Thực hiện lưu dữ liệu lịch sử với các thông số thời gian
    • Tạo chức năng tự động cập nhật dữ liệu mới
  4. Phân tích thêm chỉ báo kỹ thuật:

    • Thêm các chỉ báo như RSI, MACD, Bollinger Bands
    • Tạo hệ thống cảnh báo dựa trên các chỉ báo

🚀 Nâng cao: Tự động hóa thu thập dữ liệu và cảnh báo

Chúng ta có thể phát triển một hệ thống tự động thu thập dữ liệu định kỳ và gửi cảnh báo khi có tín hiệu kỹ thuật quan trọng:

import time
import schedule
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def analyze_btc_price():
# Lấy dữ liệu mới nhất
klines = client.get_klines(symbol='BTCUSDT', interval=Client.KLINE_INTERVAL_1HOUR, limit=100)
df = pd.DataFrame(klines, columns=[...]) # Như đã định nghĩa trước đó

# Chuyển đổi kiểu dữ liệu
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
df[['open', 'high', 'low', 'close', 'volume']] = df[['open', 'high', 'low', 'close', 'volume']].astype(float)

# Tính toán chỉ báo
df['MA20'] = df['close'].rolling(window=20).mean()
df['MA50'] = df['close'].rolling(window=50).mean()

# Kiểm tra tín hiệu giao nhau của MA
latest_row = df.iloc[-1]
previous_row = df.iloc[-2]

# Kiểm tra Golden Cross (MA20 cắt lên trên MA50)
golden_cross = previous_row['MA20'] <= previous_row['MA50'] and latest_row['MA20'] > latest_row['MA50']

# Kiểm tra Death Cross (MA20 cắt xuống dưới MA50)
death_cross = previous_row['MA20'] >= previous_row['MA50'] and latest_row['MA20'] < latest_row['MA50']

# Gửi thông báo nếu có tín hiệu
if golden_cross:
send_alert(f"Golden Cross trên BTCUSDT! Giá hiện tại: {latest_row['close']}")
elif death_cross:
send_alert(f"Death Cross trên BTCUSDT! Giá hiện tại: {latest_row['close']}")

# Lưu dữ liệu vào CSV
df.to_csv('btcusdt_historical_data.csv', index=False)

def send_alert(message):
# Cấu hình email
sender_email = "your_email@gmail.com"
receiver_email = "recipient_email@gmail.com"
password = "your_email_password"

# Tạo message
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = "Cảnh báo Crypto!"

msg.attach(MIMEText(message, 'plain'))

# Gửi email
try:
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(sender_email, password)
server.send_message(msg)
server.quit()
print("Đã gửi email cảnh báo thành công!")
except Exception as e:
print(f"Lỗi khi gửi email: {e}")

# Lên lịch chạy mỗi giờ
schedule.every().hour.do(analyze_btc_price)

# Chạy liên tục
while True:
schedule.run_pending()
time.sleep(60) # Kiểm tra mỗi phút

Lưu ý: Đoạn mã trên cần cài đặt thêm thư viện schedule bằng cách chạy pip install schedule.

📚 Kết luận

Qua bài học này, chúng ta đã:

  • Kết nối với API của Binance để lấy dữ liệu giá BTCUSDT
  • Xử lý và phân tích dữ liệu với pandas
  • Tạo biểu đồ tương tác đẹp mắt và đầy đủ thông tin với Plotly
  • Học cách tính toán chỉ báo kỹ thuật và hiển thị chúng trên biểu đồ
  • Tạo hệ thống tự động phân tích và cảnh báo

Đây là nền tảng cho việc xây dựng các hệ thống phân tích kỹ thuật và giao dịch tự động phức tạp hơn. Từ đây, bạn có thể phát triển thêm:

  • Chiến lược giao dịch tự động dựa trên các tín hiệu kỹ thuật
  • Hệ thống quản lý danh mục đầu tư tiền mã hóa
  • Phân tích cảm xúc thị trường kết hợp với phân tích kỹ thuật
  • Dự đoán giá bằng mô hình học máy

Phân tích dữ liệu không đảm bảo lợi nhuận đầu tư. Hãy luôn cẩn trọng và nghiên cứu kỹ trước khi đầu tư.